package com.zkh.myutils.io.file;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

import com.zkh.myutils.code.Charsets;
import com.zkh.myutils.io.IOUtils;
import com.zkh.myutils.utils.UtilsException;

/**
 * 快速写文件
 * @author zkh
 */
public class FileWriter {
	//写句柄
	private OutputStream os;
	private OutputStreamWriter osw;
	private BufferedWriter bw;
	
	/**
	 * 写文件构造方法
	 * @param filepath 文件绝对路径
	 */
	public FileWriter(String filepath){
		this(filepath, false);
	}
	
	/**
	 * 写文件构造方法
	 * @param filepath 文件绝对路径
	 * @param append 是否追加到文件
	 */
	public FileWriter(String filepath, boolean append){
		this(filepath, Charsets.UTF_8, append);
	}
	
	/**
	 * 写文件构造方法
	 * @param filepath 文件绝对路径
	 * @param charset 编码，不设置默认UTF-8
	 */
	public FileWriter(String filepath, Charset charset){
		this(filepath, charset, false);
	}
	
	/**
	 * 写文件构造方法
	 * @param filepath 文件绝对路径
	 * @param charset 编码。不设置默认UTF-8
	 * @param append 是否追加到文件。不设置默认false
	 */
	public FileWriter(String filepath, Charset charset, boolean append){
		this(new File(filepath), charset, append);
	}
	
	/**
	 * 写文件构造方法
	 * @param file 文件File对象
	 */
	public FileWriter(File file){
		this(file, false);
	}
	
	/**
	 * 写文件构造方法
	 * @param file 要操作的文件对象
	 * @param append 是否追加
	 */
	public FileWriter(File file, boolean append) {
		this(file, Charsets.UTF_8, append);
	}
	
	/**
	 * 写文件构造方法
	 * @param file 要操作的文件对象
	 * @param charset 编码。不设置默认UTF-8
	 */
	public FileWriter(File file, Charset charset){
		this(file, charset, false);
	}
	
	/**
	 * 写文件构造方法
	 * @param file 要操作的文件对象
	 * @param charset 编码。不设置默认UTF-8
	 * @param append 是否追加到文件。不设置默认false
	 */
	public FileWriter(File file, Charset charset, boolean append){
		try {
			os = new FileOutputStream(file, append);
			osw = new OutputStreamWriter(os, charset);
			bw = new BufferedWriter(osw);
		} catch (IOException e) {
			throw new UtilsException(e);
		}
	}
	
	/**
	 * 写内容到文件，不关闭资源，写完后自动调用flush()
	 * @param content 待保存的内容
	 */
	public void write(Object content){
		write(content, false);
	}
	
	/**
	 * 写内容到文件，写完后自动调用flush()
	 * @param content 待保存的内容
	 * @param close 写入数据后是否关闭资源
	 */
	public void write(Object content, boolean close){
		try {
			bw.write(content==null ? "null" : content.toString());
			bw.flush();
		} catch (IOException e) {
			throw new UtilsException(e);
		}
		if(close){
			close();
		}
	}
	
	/**
	 * 写内容到文件，并自动换行，不关闭资源，写完后自动调用flush()
	 * @param content 待保存的内容
	 */
	public synchronized void writeln(Object content){
		write(content);
		newLine();
	}
	
	/**
	 * 写内容到文件，并自动换行，不关闭资源，写完后自动调用flush()
	 * @param content 待保存的内容
	 * @param close 写入数据后是否关闭资源
	 */
	public synchronized void writeln(Object content, boolean close){
		write(content);
		newLine(close);
	}
	
	/**
	 * 换行，不关闭资源，写完后自动调用flush()
	 */
	public void newLine(){
		newLine(false);
	}
	
	/**
	 * 换行，写完后自动调用flush()
	 * @param close 换行后是否关闭资源
	 */
	public void newLine(boolean close){
		try {
			bw.newLine();
			bw.flush();
		} catch (IOException e) {
			throw new UtilsException(e);
		}
		if(close){
			close();
		}
	}
	
	/**
	 * 关闭资源
	 */
	public void close(){
		IOUtils.closeQuietly(bw, osw, os);
	}
}
